using System.Collections.ObjectModel;

using agsXMPP.protocol.iq.privacy;

using VSTalk.Engine.Core.EntitySession;
using VSTalk.Engine.Core.XmppConnection;
using VSTalk.Engine.Utils;
using VSTalk.Engine.ViewModel.ContactList.Filter;
using VSTalk.Engine.ViewModel.ContactList.Order;
using VSTalk.Engine.ViewModel.Editors.ContactEditor;
using VSTalk.Engine.ViewModel.Editors.RoomEditor;
using VSTalk.Engine.Windows;
using VSTalk.Model;
using VSTalk.Tools;

namespace VSTalk.Engine.ViewModel.ContactList
{
    public class ClientNodeViewModel : IListener, IPresentationSource
    {
        public Client Model { get; private set; }
        
        public IClientContext Context { get; private set; }

        public ClientResourcesManager ResourcesManager { get; set; }

        public ObservableCollection<Room> RoomSource
        {
            get
            {
                return Model.Rooms;
            }
        }

        public ObservableCollection<Interlocutor> InterlocutorSource
        {
            get
            {
                return Model.Contacts;
            }
        }

        public ObservableCollection<IClientResource> ActiveResources { get; private set; }

        public RelayCommand ShowContactEditor { get; private set; }

        public RelayCommand ShowRoomEditor { get; private set; }

        public RelayCommand ConnectClient { get; private set; }
        
        public RelayCommand DisconnectClient { get; private set; }

        private static ISessionModel SessionModel
        {
            get { return AppServices.Get<ISessionModel>(); }
        }

        private static IConnectionManager ConnectionManager
        {
            get { return AppServices.Get<IConnectionManager>(); }
        }

        public ClientNodeViewModel(Client client)
        {
            Model = client;
            Context = SessionModel.GetClientContext(client);
            ActiveResources = new ObservableCollection<IClientResource>();
            ResourcesManager = CreateResourceManager();
            SetCommands();
        }
        
        public void StartListen()
        {
            ResourcesManager.StartListen();
        }

        public void StopListen()
        {
            ResourcesManager.StopListen();
        }

        private ClientResourcesManager CreateResourceManager()
        {
            var filter = new HideOfflineContactFilter();
            var comparator = new DefaultResourceComparator();
            var manager = new ClientResourcesManager(this, filter, comparator);
            return manager;
        }

        private void SetCommands()
        {
            ShowContactEditor = new RelayCommand(ShowContactEditorExecuted);
            ShowRoomEditor = new RelayCommand(ShowRoomEditorExecuted);
            ConnectClient = new RelayCommand(ConnectClientExecuted);
            DisconnectClient = new RelayCommand(DisconnectClientExecuted);
        }

        private void DisconnectClientExecuted()
        {
            ConnectionManager.Disconnect(Model);
        }

        private void ConnectClientExecuted()
        {
            ConnectionManager.Connect(Model);
        }

        private void ShowRoomEditorExecuted()
        {
            var roomVM = new RoomEditorViewModel(Model);
            var roomEditor = new RoomEditorWindow();
            roomEditor.DataContext = roomVM;
            roomVM.Rejected += roomEditor.Close;
            roomVM.Saved += roomEditor.Close;
            roomEditor.Show();
        }

        private void ShowContactEditorExecuted()
        {
            var contactVm = new ContactEditorViewModel(Model);
            var contact = new ContactEditorWindow();
            contact.DataContext = contactVm;
            contactVm.Rejected += contact.Close;
            contactVm.Saved += contact.Close;
            contact.Show();
        }
    }
}